import base64
import pickle

from django.shortcuts import render, redirect
from django.views import View
from django.http import HttpResponseForbidden, JsonResponse

import json

from django_redis import get_redis_connection

from meiduo_mall.utils.response_code import RETCODE
# Create your views here.



# sku_id: this.carts[index].id,
# count: count,
# selected: this.carts[index].selected

# sku_id: parseInt(this.sku_id),
# count: this.sku_count
from contents.models import SKU


class CartsIndexView(View):
    '''购物车首页'''
    def get(self,request):
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            # hgetall 取不到值会返回一个空列表
            sku_dict_byte = redis_conn.hgetall('carts%s' % request.user.id)
            if not sku_dict_byte:    # 此处判断空列表不能写成is False
                return render(request,'cart.html')
            # smember 取不到值会返回一个空集
            sku_id_selected = redis_conn.smembers('selected%s'%request.user.id)
            cart_skus = []
            for sku_id in sku_dict_byte.keys():
                sku = SKU.objects.get(id=int(sku_id))
                count = int(sku_dict_byte[sku_id])
                cart_skus.append({
                    'id':sku.id,
                    'name':sku.name,
                    'price':str(sku.price),
                    'count':count,
                    'amount':str(sku.price * count),
                    'selected': str(sku_id in sku_id_selected),
                    'default_image_url':sku.default_image.url
                })
        else:
            cookie_byte = request.COOKIES.get('carts')
            if not cookie_byte:
                return render(request,'cart.html')
            cookie_dict = pickle.loads(base64.b64decode(cookie_byte.encode()))
            cart_skus = []
            for sku_id in cookie_dict.keys():
                sku = SKU.objects.get(id=sku_id)
                # 此处注意数据类型的转换
                cart_skus.append({
                    'id':sku.id,
                    'name':sku.name,
                    'default_image_url':sku.default_image.url,
                    'count':cookie_dict[sku_id]['count'],
                    'selected':str(cookie_dict[sku_id]['selected']),
                    'price':str(sku.price),
                    'amount':str(sku.price * cookie_dict[sku_id]['count'])
                })
        return render(request,'cart.html',{'cart_skus':cart_skus})
    def post(self,request):
        json_dict=json.loads(request.body)
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected',True)
        if not all([sku_id,count]):
            return HttpResponseForbidden('缺少参数')
        try:
            sku = SKU.objects.get(id = sku_id)
        except SKU.DoesNotExist:
            return HttpResponseForbidden('没有此id')
        try:
            count = int(count)
        except:
            return HttpResponseForbidden('count错误')
        if not isinstance(selected,bool):
            return HttpResponseForbidden('selected错误')

        if not request.user.is_authenticated:
            cookie_byte = request.COOKIES.get('carts')
            if not cookie_byte:
                cookie_dict = {}
            else:
                cookie_dict = pickle.loads(base64.b64decode(cookie_byte.encode()))
                if sku_id in cookie_dict:
                    count = cookie_dict.get(sku_id).get('count') + count
            cookie_dict[sku_id] = {
                'count':count,
                'selected':selected
            }
            # byte_cookie = pickle.dumps(cookie_dict)
            # bytes_cookie = base64.b64encode(byte_cookie)
            # cookie = base64.b64decode(bytes_cookie)
            cookie = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response = JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
            response.set_cookie('carts',cookie)
            return response
        else:
            redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            pl.hincrby('carts%s' % request.user.id,sku_id,count)
            if selected:
                pl.sadd('selected%s' % request.user.id,sku_id)
            pl.execute()
            return JsonResponse({'code':RETCODE.OK,'errmsg':'添加购物车成功'})

    # sku_id: this.carts[index].id,
    # count: count,
    # selected: this.carts[index].selected
    def put(self,request):
        json_dict = json.loads(request.body)
        sku_id = json_dict.get('sku_id')
        count = json_dict.get('count')
        selected = json_dict.get('selected')
        if not all([sku_id,count]):
            return HttpResponseForbidden('缺少参数')
        if not isinstance(selected,bool):
            return HttpResponseForbidden('参数错误')
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return HttpResponseForbidden('ID错误')
        if not int(count):
            return HttpResponseForbidden('count错误')
        cart_sku = {
            'id':sku.id,
            'count': count,
            'selected': selected,  #  这里写错了会使前端页面的钩无法消除
            'name':sku.name,
            'default_image_url':sku.default_image.url,
            'price':str(sku.price),
            'amount':str(sku.price*count)
        }
        response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'cart_sku':cart_sku})
        if request.user.is_authenticated:
            # 注意连接到数据库的名字
            redis_conn = get_redis_connection('carts')
            redis_conn.hset('carts%s' % request.user.id,sku_id,count)
            if selected:
                # 已经存在的集合元素将被忽略
                redis_conn.sadd('selected%s' %request.user.id,sku_id)
            else:
                redis_conn.srem('selected%s' %request.user.id,sku_id)


        else:
            cookie_byte = request.COOKIES.get('carts')
            if not cookie_byte:
                return render(request,'cart.html')
            cookie_dict = pickle.loads(base64.b64decode(cookie_byte.encode()))
            cookie_dict[sku_id]['count'] = count
            cookie_dict[sku_id]['selected'] = selected
            cookie = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie('carts',cookie)
        return response

    def delete(self,request):
        json_dict = json.loads(request.body)
        sku_id = json_dict.get('sku_id')
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return HttpResponseForbidden('id不存在')
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            redis_conn.hdel('carts%s'%request.user.id,sku_id)
            redis_dict = redis_conn.hgetall('carts%s'%request.user.id)
            if not redis_dict:
                del redis_dict
            redis_conn.srem(f'selected{request.user.id}',sku_id)
            return JsonResponse({'code':RETCODE.OK,'errmsg':'删除成功'})
        else:
            cookie_bytes = request.COOKIES.get('carts')
            if not cookie_bytes:
                return HttpResponseForbidden('cookie不存在')
            cookie_dict = pickle.loads(base64.b64decode(cookie_bytes.encode()))
            if sku_id not in cookie_dict:
                return HttpResponseForbidden('cookie不存在sku_id')
            del cookie_dict[sku_id]
            response = JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
            if not cookie_dict:
                response.delete_cookie('carts')
            cookie = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie('carts',cookie)
            return response

class SelectedAll(View):
    def put(self,request):
        json_dict = json.loads(request.body)
        selected = json_dict.get('selected')
        if selected:
            if not isinstance(selected,bool):
                return HttpResponseForbidden('selected错误')
        if selected:
            if request.user.is_authenticated:
                redis_conn = get_redis_connection('catrs')
                accrent_user_sku_list = redis_conn.hkeys('carts%s'%request.user.id)
                if not accrent_user_sku_list:
                    return HttpResponseForbidden('当前无任何购物车数据')
                for user_sku in accrent_user_sku_list:
                    redis_conn.sadd('selected%s'%request.user.id,user_sku)
                return JsonResponse({'code':RETCODE.OK,'errmsg':'OK'})
            else:
                cookie_bytes = request.COOKIES.get('carts')
                if not cookie_bytes:
                    return HttpResponseForbidden('没有cookie值')
                cookie_dict = pickle.loads(base64.b64decode(cookie_bytes.encode()))
                for sku_dict in cookie_dict.values():
                    sku_dict['selected'] = selected
                cookie = base64.b64encode(pickle.dumps(cookie_dict)).decode()
                response = JsonResponse({'code':RETCODE.OK,'errmsg':'OK'})
                response.set_cookie('carts',cookie)
                return response
        else:
            if request.user.is_authenticated:
                redis_conn = get_redis_connection('carts')
                selected_set = redis_conn.smembers('selected%s'%request.user.id)
                del selected_set
                return JsonResponse({'code':RETCODE.OK,'errmsg':'已经删除selected'})
            else:
                cookie_bytes = request.COOKIES.get('carts')
                if not cookie_bytes:
                    return HttpResponseForbidden('cookie不存在')
                cookie_dict = pickle.loads(base64.b64decode(cookie_bytes.encode()))
                for sku_dict in cookie_dict.values():
                    sku_dict['selected'] = selected
                cookie = base64.b64encode(pickle.dumps(cookie_dict)).decode()
                response = JsonResponse({'code':RETCODE.OK,'errmsg':'已成功删除'})
                response.set_cookie('carts',cookie)
                return response

class CartsSimple(View):
    def get(self,request):
        if request.user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            sku_dict = redis_conn.hgetall('carts%s' %request.user.id)
            if not sku_dict:
                return JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '无数据', 'cart_skus': []})
            carts = {}
            for sku_id,count in sku_dict.items():
                carts[int(sku_id)] = int(count)
        else:
            cookie_bytes = request.COOKIES.get('carts')
            if not cookie_bytes:
                return JsonResponse({'code':RETCODE.NODATAERR,'errmsg':'无数据','cart_skus':[]})
            cookie_dict = pickle.loads(base64.b64decode(cookie_bytes.encode()))
            carts = {}
            for sku_id,values in cookie_dict.items():
                carts[sku_id] = values['count']
        sku_qs = SKU.objects.filter(id__in=carts.keys())
        cart_skus = []
        for sku in sku_qs:
            cart_skus.append({
                'count':carts[sku.id],
                'name':sku.name,
                'default_image_url':sku.default_image.url
            })

        return JsonResponse({'code':RETCODE.OK,'errmsg':'OK','cart_skus':cart_skus})







